package org.example._04_TankWar;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random;


public class Tank {
	private int x,y;
	private int oldx,oldy;
	private static final int XSPEED=5;
	private static final int YSPEED=5;

	private static final int WIDTH=30;
	private static final int HEIGHT=30;
	TankClient tc;
	private boolean good;
	public boolean isGood() {
		return good;
	}
	private boolean Live = true;
	private BloodBar bb = new BloodBar();

	private int life = 100;

	public int getLife() {
		return life;
	}
	public void setLife(int life) {
		this.life = life;
	}
	private static Random r = new Random();
	private int step=r.nextInt(15)+3;

	public boolean isLive() {
		return Live;
	}
	public void setLive(boolean live) {
		Live = live;
	}
	private boolean bL=false,bU=false,bR=false,bD=false;
	enum Direction {L,LD,D,RD,R,RU,U,LU,STOP};

	public  Direction dir = Direction.STOP;
	private Direction PtDir = Direction.D;

	public Tank(int x, int y,boolean good) {
		this.x = x;
		this.y = y;
		this.oldx=x;
		this.oldy=y;
		this.good=good;
	}
	public Tank(int x, int y, boolean good, Direction dir, TankClient tc)
	{
		this(x,y,good);
		this.dir=dir;
		this.tc = tc;
	}

	public void draw(Graphics g)
	{
		if(!Live)
			{
				if(!good){
					tc.Tanks.remove(this);
				}
				return;
			}
		Color c = g.getColor();
		if(good) {
			g.setColor(Color.red);
		} else {
			g.setColor(Color.cyan);
		}
		g.fillOval(x, y, WIDTH, HEIGHT);
		g.setColor(c);

		if(good) {
			bb.draw(g);
		}

		switch(PtDir){
		case L:
			g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y + Tank.HEIGHT/2);
			break;
		case LD:
			g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y + Tank.HEIGHT);
			break;
		case D:
			g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH/2, y + Tank.HEIGHT);
			break;
		case RD:
			g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y + Tank.HEIGHT);
			break;
		case R:
			g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y + Tank.HEIGHT/2);
			break;
		case RU:
			g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH, y );
			break;
		case U:
			g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x + Tank.WIDTH/2, y);
			break;
		case LU:
			g.drawLine(x + Tank.WIDTH/2, y + Tank.HEIGHT/2, x, y);
			break;
		}
		move();

	}
	void move()
	{
		this.oldx=x;
		this.oldy=y;

		switch(dir){
		case L:
			x-=XSPEED;
			break;
		case LD:
			x-=XSPEED;
			y+=YSPEED;//此处是减法，不是加法，因为frame中左上方坐标是（0,0）
			break;
		case D:
			y+=YSPEED;
			break;
		case RD:
			x+=XSPEED;
			y+=YSPEED;
			break;
		case R:
			x+=XSPEED;
			break;
		case RU:
			x+=XSPEED;
			y-=YSPEED;
			break;
		case U:
			y-=XSPEED;
			break;
		case LU:
			x-=XSPEED;
			y-=XSPEED;
			break;
		case STOP:
			break;
		}
		if(dir != Direction.STOP)
		{
			this.PtDir= this.dir;
		}
		if(x<0) {
			x=0;
		}
		if(y<30) {
			y=30;
		}
		if(x> TankClient.GAME_WIDTH) {
			x= TankClient.GAME_WIDTH-50;
		}
		if(y> TankClient.GAME_HEIGHT) {
			y= TankClient.GAME_HEIGHT-50;
		}

		if(!good){
			Direction[] dirs = Direction.values();
			if(step == 0)
			{
				int rn = r.nextInt(dirs.length);
				dir =dirs[rn];
				step=r.nextInt(15)+3;
			}
		step--;
		if (r.nextInt(45)>40) {
			this.fire();
		}
		}

	}
	public void keyPressed(KeyEvent e) {
		int Key=e.getKeyCode();
		switch(Key)
		{
		case KeyEvent.VK_O:
		if(!Live)
		{
			this.Live=true;
			this.life=100;
		}
		break;
			case KeyEvent.VK_A :
				bL=true;
				break;
			case KeyEvent.VK_S :
				bD=true;
				break;
			case KeyEvent.VK_D :
				bR=true;
				break;
			case KeyEvent.VK_W :
				bU=true;
				break;
		}
		locateDircetion();
	}
	void locateDircetion()
	{
		if(bL && !bD && !bR && !bU) {
			dir =Direction.L;
		} else if(bL && bD && !bR && !bU) {
			dir =Direction.LD;
		} else if(!bL && bD && !bR && !bU) {
			dir =Direction.D;
		} else if(!bL && bD && bR && !bU) {
			dir =Direction.RD;
		} else if(!bL && !bD && bR && !bU) {
			dir =Direction.R;
		} else if(!bL && !bD && bR && bU) {
			dir =Direction.RU;
		} else if(!bL && !bD && !bR && bU) {
			dir =Direction.U;
		} else if(bL && !bD && !bR && bU) {
			dir =Direction.LU;
		} else if(!bL && !bD && !bR && !bU) {
			dir =Direction.STOP;
		}
	}

	public void keyReleased(KeyEvent e) {
		int Key=e.getKeyCode();
		switch(Key)
		{
			case KeyEvent.VK_J:
				fire();
				break;
			case KeyEvent.VK_A :
				bL=false;
				break;
			case KeyEvent.VK_S :
				bD=false;
				break;
			case KeyEvent.VK_D :
				bR=false;
				break;
			case KeyEvent.VK_W :
				bU=false;
				break;
			case KeyEvent.VK_U:
				SuperFire();
		}
		locateDircetion();

	}
	public Missile fire()
	{
		if(!Live) {
			return null;
		}
		int x=this.x+Tank.WIDTH/2 - Missile.WIDTH/2;
		int y=this.y+Tank.WIDTH/2 - Missile.WIDTH/2;
		Missile m = new Missile(x,y,good,PtDir,this.tc);
		tc.missiles.add(m);
		return m;
	}
	public Rectangle getRec()
	{
		return new Rectangle(x,y,WIDTH,HEIGHT);
	}
	/**
	 *坦克撞上墙的方法。
	 * @param w 被撞的墙。
	 * @return 撞上，返回值为true，没撞上返回值为false。
	 */
	public boolean collidesWall(Wall w)
	{
		if(this.Live && this.getRec().intersects(w.getRec()))
		{
			this.stay();
				return true;
		}
		return false;
	}
	public void stay()
	{
		x=oldx;
		y=oldy;
	}
	public boolean HitTanks(List<Tank> Tanks)
	{
		for(int x=0; x<Tanks.size();x++)
		{
			Tank t =Tanks.get(x);
			if(this!=t)
					{
						if(this.Live && this.getRec().intersects(t.getRec()))
						{
							this.stay();
							t.stay();
								return true;
						}
					}
		}
		return false;
	}
	public Missile fire(Direction dir)
	{
		if(!Live) {
			return null;
		}
		int x=this.x+Tank.WIDTH/2 - Missile.WIDTH/2;
		int y=this.y+Tank.WIDTH/2 - Missile.WIDTH/2;
		Missile m = new Missile(x,y,good,dir,this.tc);
		tc.missiles.add(m);
		return m;
	}
	public void SuperFire()
	{
		Direction[] dirs = Direction.values();
		for(int x=0; x<8;x++)
		{
			fire(dirs[x]);
		}
	}
	public class BloodBar
	{
		public void draw(Graphics g)
		{
			Color c =g.getColor();
			g.setColor(Color.red);
			g.drawRect(x, y-10, WIDTH, 10);
			int w =WIDTH*life/100;
			g.fillRect(x, y-10, w, 10);
			g.setColor(c);
		}
	}
	public boolean eat(Blood b)
	{
		if(this.Live &&b.isLive() && this.getRec().intersects(b.getRect()))
		{
			this.life=100;
			b.setLive(false);
				return true;
		}
		return false;
	}
}
//	public static void main(String[] args) {
//		// TODO Auto-generated method stub
//
//	}

	
